#include "precompile.h"
#include "base_delegate.h"

_SSL_BEGIN
_SSBASEL_BEGIN

delegate_base::delegate_base(void *obj, void *fn)
{
	object_ = obj;
	function_ = fn;
}

delegate_base::delegate_base(const delegate_base &rhs)
{
	object_ = rhs.object_;
	function_ = rhs.function_;
}

delegate_base::~delegate_base()
{

}

bool delegate_base::equal(const delegate_base &rhs) const
{
	return object_ == rhs.object_ && function_ == rhs.function_;
}

bool delegate_base::operator ()(void *param)
{
	return invoke(param);
}

void* delegate_base::get_function()
{
	return function_;
}

void* delegate_base::get_object()
{
	return object_;
}

delegate_static::delegate_static(func_ptr pfn)
	: delegate_base(NULL, pfn)
{

}

delegate_static::delegate_static(const delegate_static &rhs)
	: delegate_base(rhs)
{

}

delegate_base* delegate_static::copy()
{
	return new delegate_static(*this);
}

bool delegate_static::invoke(void *param)
{
	func_ptr pfn = (func_ptr)get_function();
	return (pfn)(param);
}

event_source::event_source()
{

}

event_source::~event_source()
{
	for(delegate_base_ptrs::iterator iter=delegates_.begin(); iter!=delegates_.end(); iter++)
	{
		delegate_base *deleg = *iter;
		if(deleg != NULL)
			delete deleg;
	}
	delegates_.clear();
}

event_source::operator bool()
{
	return delegates_.size() > 0;
}

void event_source::operator += (delegate_base &d)
{
	for(delegate_base_ptrs::iterator iter=delegates_.begin(); iter!=delegates_.end(); iter++)
	{
		delegate_base *deleg = *iter;
		if(deleg != NULL && deleg->equal(d))
			return;
	}
	delegates_.push_back(d.copy());
}

void event_source::operator += (func_ptr pfn)
{
	(*this) += make_delegate(pfn);
}

void event_source::operator -= (delegate_base &d)
{
	for(delegate_base_ptrs::iterator iter=delegates_.begin(); iter!=delegates_.end(); iter++)
	{
		delegate_base *deleg = *iter;
		if(deleg != NULL && deleg->equal(d))
		{
			delete deleg;
			delegates_.erase(iter);
			return;
		}
	}
}

void event_source::operator -= (func_ptr pfn)
{
	(*this) -= make_delegate(pfn);
}

bool event_source::operator()(void *param)
{
	for(delegate_base_ptrs::iterator iter=delegates_.begin(); iter!=delegates_.end(); iter++)
	{
		delegate_base *deleg = *iter;
		if(deleg != NULL && !(*deleg)(param))
			return false;
	}
	return true;
}


_SSBASEL_END
_SSL_END

